import os
import log
import bitbrowser_api as api
import pyppeteer
import asyncio


choice_list = ["工具","家具","生活用品","园艺","电气","电子游戏","书籍、电影和音乐",'行李箱包',"女士服装和鞋类","男装男鞋","珠宝与配饰","保健/美容","宠物用品","婴幼儿用品","玩具与游戏","电子/电脑",'手机',"自行车","艺术与工艺品","运动/户外","汽车零件","乐器","古董与收藏","二手货甩卖","其他"]
codition_list = ["全新","二手 - 几乎全新","二手 - 成色好","二手 - 成色尚可"]
inventory_status_list = ["有货","仅此一件"]

async def upshelf(ws_link :str,img_files :list,title :str,price :str,choice :int,status :int,description :str,inventory_status :int,position :str,meet_public :bool,deliever :bool,hide :bool):
# async def upshelf():
    """
    上传商品到Facebook市场
    :param ws_link: 浏览器ws链接
    :param img_files: 图片文件路径列表
    :param title: 商品标题
    :param price: 商品价格
    :param choice: 商品分类
    :param status: 商品状态
    :param description: 商品描述
    :param inventory_status: 库存状态
    :param position: 商品位置
    :param meet_public: 是否公开
    :param deliever: 是否允许交付
    :param hide: 是否隐藏
    :return: 上传成功返回True，否则返回False
    """
    # img_files :list = ["C:/Users/ZZH/Pictures/OIP-C.jpg"]
    # title :str = "Title"
    # price :str = "1000"

    # choice = 9 + 1
    # status = 3

    # description :str = "Description"
    # inventory_status = 1
    # position :str = "杭州"

    # meet_public = True
    # deliever = True
    # hide = True
    '''
    连接并打开网页
    '''
    try:
        log.Info("连接并打开网页")
        # ws_link = api.get_pyppeteer_wslink_by_ids(api.get_alive_ids()[0])
        log.Info(f"Link to browser[{ws_link}]")

        # 连接浏览器
        browser = await pyppeteer.connect(
            browserWSEndpoint=ws_link,
            ignoreHTTPSErrors=True,
            args=['--no-sandbox']
        )
        # 创建新页面
        page = await browser.newPage()
        # 设置窗口大小为1024x768
        await page.setViewport({'width': 1024, 'height': 768})

        # 导航到目标 URL
        await page.goto("https://www.facebook.com/marketplace/create/item")
        
        # 等待页面加载完成
        await page.waitForSelector('body')
        # 获取页面内容
        content = await page.content()

        # 获取所有输入框
        # input_fields = await page.querySelectorAll('.x1i10hfl.xggy1nq.xtpw4lu.x1tutvks.x1s3xk63.x1s07b3s.x1kdt53j.x1a2a7pz.xjbqb8w.x1ejq31n.x18oe1m7.x1sy0etr.xstzfhl.x9f619.xzsf02u.x1uxerd5.x1fcty0u.x132q4wb.x1a8lsjc.xv54qhq.xf7dkkf.x9desvi.xh8yej3')
        
        # # 点击第一个输入框输入标题
        # if len(input_fields) > 0:
        #     for chr in title:
        #         await input_fields[0].type(chr)
        #         await asyncio.sleep(0.1)
        
        # # 在第二个输入框输入价格
        # if len(input_fields) > 1:
        #     for chr in price:
        #         await input_fields[1].type(chr)
        #         await asyncio.sleep(0.1)

        try:
            title_label = await page.waitForXPath('//span[contains(text(), "标题")]', timeout=10000)
            title_input = await title_label.xpath('following::input[1]')
            for char in title:
                await title_input[0].type(char)
                await asyncio.sleep(0.1)
            await asyncio.sleep(1)
            log.Info("标题输入成功")

            price_label = await page.waitForXPath('//span[contains(text(), "价格")]', timeout=10000)
            price_input = await price_label.xpath('following::input[1]')
            for char in price:
                await price_input[0].type(char)
                await asyncio.sleep(0.1)
            await asyncio.sleep(1)
            log.Info("价格输入成功")
        except Exception as e:
            log.Error(f"Error details: {str(e)}")
            return False

    except Exception as e:
        log.Error(f"Error details: {str(e)}")
        log.Error(f"Error type: {type(e).__name__}")
        if hasattr(e, 'args'):
            log.Error(f"Error args: {e.args}")
        return False
    
    '''
    选择种类
    '''
    
    try:
        log.Info("选择种类")

        try:
        # 点击第一个目标元素
            choice_lable = await page.waitForXPath('//span[contains(text(), "类别")]', timeout=1000)
            await choice_lable.click()
            await asyncio.sleep(1)
        except Exception as e:
            try:
                log.Info("备用方案")
                # 查找所有具有指定class的元素
                elements = await page.querySelectorAll('.xjhjgkd.x1epquy7.x1ca8kz.x1562eck.xcclseo.x11lwdb5.xfxe0gy.x1szzd0g.xh2argp.x13fuv20.x18b5jzi.x1q0q8m5.x1t7ytsu.xq2ru2l.x1481eag.xjmv2fv.x1gx2yb3.x78zum5.xdt5ytf.x6ikm8r.x10wlt62.x1n2onr6.x1ja2u2z.x1bb484j.x1ypdohk.x1a2a7pz')
                
                # 检查是否找到足够的元素
                if len(elements) >= 0:
                    # 点击第三个元素（索引为2）
                    await elements[0].click()
                    await asyncio.sleep(1)
                    log.Info("第三个指定class的元素点击成功")
                else:
                    log.Warning(f"未找到足够的目标元素，只找到{len(elements)}个元素")
                    return False
            except Exception as e:
                log.Error(f"Error details: {str(e)}")
                return False
        
        # 按tab经行选择
        for _ in range(choice-1):
            await page.keyboard.press('Tab')
            await asyncio.sleep(0.1)
        
        # 按回车确认选择
        await page.keyboard.press('Enter')
        await asyncio.sleep(1)

    except Exception as e:
        log.Error(f"Error details: {str(e)}")
        return False


    '''
    选择状态
    '''
    try:
        log.Info("选择状态")

        try:
            choice_lable = await page.waitForXPath('//span[contains(text(), "商品状况")]', timeout=10000)
            await choice_lable.click()
            await asyncio.sleep(1)
        except Exception as e:
            try:
                log.Info("备用方案")
                elements = await page.querySelectorAll('.xjhjgkd.x1epquy7.x1ca8kz.x1562eck.xcclseo.x11lwdb5.xfxe0gy.x1szzd0g.xh2argp.x13fuv20.x18b5jzi.x1q0q8m5.x1t7ytsu.xq2ru2l.x1481eag.xjmv2fv.x1gx2yb3.x78zum5.xdt5ytf.x6ikm8r.x10wlt62.x1n2onr6.x1ja2u2z.x1bb484j.x1ypdohk.x1a2a7pz')
                
                # 检查是否找到足够的元素
                if len(elements) >= 0:
                    # 点击第三个元素（索引为2）
                    await elements[1].click()
                    await asyncio.sleep(1)
                    log.Info("第三个指定class的元素点击成功")
                else:
                    log.Warning(f"未找到足够的目标元素，只找到{len(elements)}个元素")
                    return False
            except Exception as e:
                log.Error(f"Error details: {str(e)}")
                return False

        # 按下箭头键选择状态
        for _ in range(status):
            await page.keyboard.press('ArrowDown')
            await asyncio.sleep(0.2)
        
        # 按回车确认选择
        await page.keyboard.press('Enter')
        await asyncio.sleep(1)

    except Exception as e:
        log.Error(f"Error details: {str(e)}")
        return False


    '''
    添加描述
    '''
    try:
        log.Info("添加描述")

        # 修正选择器，类名之间用点号连接
        desc_input = await page.querySelectorAll('.x1i10hfl.xggy1nq.xtpw4lu.x1tutvks.x1s3xk63.x1s07b3s.xjbqb8w.x1ejq31n.x18oe1m7.x1sy0etr.xstzfhl.x9f619.xzsf02u.x78zum5.x1jchvi3.x1fcty0u.x1a2a7pz.x6ikm8r.xv54qhq.xf7dkkf.xtt52l0.xh8yej3.x1ls7aod.xcrlgei.x1byulpo.x1agbcgv.x15bjb6t')
        
        # 检查是否找到元素
        if desc_input:
            # 点击第一个匹配的元素
            await desc_input[0].click()
            # 输入描述内容
            for chr in description:
                # 调用具体元素的 type 方法
                await desc_input[0].type(chr)
                await asyncio.sleep(0.1)
            await asyncio.sleep(1)  # 等待输入完成
        else:
            log.Warning("未找到描述输入框元素")

        # title_label = await page.waitForXPath('(//span[contains(text(), "说明")])[2]', timeout=10000)
        # title_input = await title_label.xpath('following::input[1]')
        # for char in description:
        #     await title_input[0].type(char)
        #     await asyncio.sleep(0.1)
        # await asyncio.sleep(1)

    except Exception as e:
        log.Error(f"Error details: {str(e)}")
        return False


    '''
    选择库存
    '''
    try:
        if inventory_status == 0:
            log.Info("选择库存")
            # 点击第三个目标元素
            inventory_label = await page.waitForXPath('//span[contains(text(), "库存状态")]', timeout=10000)
            await inventory_label.click()
            await asyncio.sleep(1)
            log.Info("库存点击成功")

            # 点击第inventory_status个目标元素
            status_label = await page.waitForXPath('//span[contains(text(), "显示为“有货”")]', timeout=10000)
            await status_label.click()
            log.Info("库存状态输入成功")

    except Exception as e:
        log.Error(f"Error details: {str(e)}")
        return False
    
    '''
    选择地点
    '''
    try:
        log.Info("选择地点")

        title_label = await page.waitForXPath('//span[contains(text(), "位置")]', timeout=10000)
        title_input = await title_label.xpath('following::input[1]')
        for char in position:
            await title_input[0].type(char)
            await asyncio.sleep(0.1)
        await asyncio.sleep(2)
        log.Info("位置输入成功")

        title_label = await page.waitForXPath(f"(//span[contains(text(), \"{position}\")])[2]", timeout=10000)
        title_input = await title_label.click()
        # for char in position:
        #     await title_input[0].type(char)
        #     await asyncio.sleep(0.1)
        # await asyncio.sleep(1)
        log.Info("位置输入成功")
                
    except:
        try:
            # # 修正选择器格式，使用点号连接类名
            # fourth_element = await page.querySelectorAll('.x193iq5w.xeuugli.x13faqbe.x1vvkbs.x1xmvt09.x1lliihq.x1s928wv.xhkezso.x1gmr53x.x1cpjm7i.x1fgarty.x1943h6x.xudqn12.x3x7a5m.x6prxxf.xvq8zen.xk50ysn.xzsf02u.x1yc453h')
            # log.Debug(f"length of [fourth_element]:{len(fourth_element)}")

            # if len(fourth_element) > 3:
            #     await fourth_element[3].click()
            #     await asyncio.sleep(1)  # 等待操作完成
            # else:
            #     log.Warning("未找到足够的目标元素")
            #     return False
            log.Info("选择地点")        # 触发报错
        except Exception as e:
            log.Error(f"Error details: {str(e)}")
            return False


    '''
    上传照片
    '''
    try:
        log.Info("上传照片")
        # 使用更精确的选择器，根据提供的 class 信息
        selector = 'input[type="file"]'
        # 等待上传框加载完成，增加超时时间
        await page.waitForSelector(selector, timeout=10000)
        upload_box = await page.querySelector(selector)

        if upload_box:
            # 上传每张图片
            for img_file in img_files:
                # 检查文件是否存在
                import os
                if not os.path.exists(img_file):
                    log.Warning(f"文件 {img_file} 不存在，跳过上传")
                    continue
                await upload_box.uploadFile(img_file)
                # 增加等待时间，确保上传完成
                await asyncio.sleep(5)  
                # 检查是否上传成功，可根据页面元素判断
                try:
                    # 假设上传成功后会出现特定元素，这里需要根据实际情况修改
                    await page.waitForSelector('.upload-success-indicator', timeout=5000)
                    log.Info(f"文件 {img_file} 上传成功")
                except pyppeteer.errors.TimeoutError:
                    log.Warning(f"文件 {img_file} 上传可能失败")
        else:
            log.Warning("未找到上传框元素")   
            return False

    except Exception as e:
        log.Error(f"Error details: {str(e)}")
        return False


    '''
    设置可见范围等等
    '''
    try:
        log.Info("设置可见范围等等")
        
        # 点击第一个元素
        if meet_public:
            inventory_label = await page.waitForXPath('//span[contains(text(), "公共场所见面")]', timeout=10000)
            await inventory_label.click()
            await asyncio.sleep(1)
        
        # 点击第三个元素
        if deliever:
            inventory_label = await page.waitForXPath('//span[contains(text(), "送货上门")]', timeout=10000)
            await inventory_label.click()
            await asyncio.sleep(1)
        
        # 点击第二个匹配的元素
        if hide:
            inventory_label = await page.waitForXPath('//span[contains(text(), "对好友隐藏")]', timeout=10000)
            await inventory_label.click()
            await asyncio.sleep(1)


    except Exception as e:
        log.Error(f"Error details: {str(e)}")
        return False


    '''
    点击下一页
    '''
    try:
        log.Info("点击下一页元素")
        # 等待并点击具有指定class的元素
        opload_lable = await page.waitForXPath('//span[contains(text(), "下一页")]', timeout=10000)
        await opload_lable.click()
        await asyncio.sleep(1)
        log.Info("元素点击成功")
    except:
        try:
            class_name = "x1i10hfl xjbqb8w x1ejq31n x18oe1m7 x1sy0etr xstzfhl x972fbf x10w94by x1qhh985 x14e42zd x1ypdohk xe8uvvx xdj266r x14z9mp xat24cr x1lziwak xexx8yu xyri2b x18d9i69 x1c1uobl x16tdsg8 x1hl2dhg xggy1nq x1fmog5m xu25z0z x140muxe xo1y3bh x87ps6o x1lku1pv x1a2a7pz x9f619 x3nfvp2 xdt5ytf xl56j7k x1n2onr6 xh8yej3"
            # 将class_name转换为CSS选择器
            selector = f".{class_name.replace(' ', '.')}"
            # 获取所有匹配的元素
            elements = await page.querySelectorAll(selector)

            # 检查是否找到足够的元素
            if len(elements) >= 3:
                # 点击第二个元素（索引为1）
                await elements[-1].click()
                await asyncio.sleep(1)
                log.Info("第二个指定class的元素点击成功")
            else:
                log.Warning(f"未找到足够的目标元素，只找到{len(elements)}个元素")

        except Exception as e:
            log.Error(f"点击元素时出错: {str(e)}")
            return False


    '''
    点击发布
    '''
    try:
        log.Info("点击发布")
        # 修改XPath表达式，使用索引[3]来定位第三个发布按钮
        opload_lable = await page.waitForXPath('(//span[contains(text(), "发布")])[3]', timeout=10000)
        await opload_lable.click()
        await asyncio.sleep(1)
        opload_lable = await page.waitForXPath('(//span[contains(text(), "发布")])[4]', timeout=10000)
        await opload_lable.click()
        await asyncio.sleep(1)
        opload_lable = await page.waitForXPath('(//span[contains(text(), "发布")])[5]', timeout=10000)
        await opload_lable.click()
        log.Info("元素点击成功")
    except Exception as e:
        try:
            log.Info("备用方案")
            class_name = "x1i10hfl x1ejq31n x18oe1m7 x1sy0etr xstzfhl x972fbf x10w94by x1qhh985 x14e42zd x9f619 x1ypdohk xe8uvvx xdj266r x14z9mp xat24cr x1lziwak x16tdsg8 x1hl2dhg xggy1nq x87ps6o x1lku1pv x1a2a7pz x6s0dn4 xmjcpbm x12ol6y4 x180vkcf x1khw62d x709u02 x78zum5 x1q0g3np x1iyjqo2 x1nhvcw1 x1n2onr6 xt7dq6l x1ba4aug x1y1aw1k xpdmqnj xwib8y2 x1g0dm76"
            # 将class_name转换为CSS选择器
            selector = f".{class_name.replace(' ', '.')}"
            # 获取所有匹配的元素
            elements = await page.querySelectorAll(selector)

            # 检查是否找到足够的元素
            if len(elements) >= 2:
                # 点击第二个元素（索引为1）
                await elements[1].click()
                await asyncio.sleep(1)
                log.Info("第二个指定class的元素点击成功")
            else:
                log.Warning(f"未找到足够的目标元素，只找到{len(elements)}个元素")

        except Exception as e:
            log.Error(f"备用方案失败: {str(e)}")
            return False

    return True

if __name__ == "__main__":
    ws_link = api.get_pyppeteer_wslink_by_ids(api.get_alive_ids()[0])
    img_files :list = ["C:/Users/ZZH/Pictures/OIP-C.jpg"]
    title :str = "Title"
    price :str = "1000"

    choice = 9 + 1
    status = 3

    description :str = "Description"
    inventory_status = 1
    position :str = "杭州"

    meet_public = True
    deliever = True
    hide = True
    asyncio.run(upshelf(ws_link,img_files,title,price,choice,status,description,inventory_status,position,meet_public,deliever,hide))  # Run the asynchronous function using asyncio.run
    # print(get_child_folder_names(["D:\\Tools\\CPU-Z"]))

